﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

namespace DesignByFarooq.PowershellByExample
{
    public sealed class MemoryStatusFilePartitionCollection : ICollection<MemoryStatusFilePartition>
    {
        private readonly List<MemoryStatusFilePartition> partitions = new List<MemoryStatusFilePartition>();

        public string InputFile { get; private set; }

        public MemoryStatusFilePartitionCollection(
            string inputFile
            )
        {
            if (string.IsNullOrEmpty(inputFile))
            {
                throw new ArgumentException(
                    "Parameter cannot be null or empty.",
                    "inputFile"
                    );
            }

            this.InputFile = inputFile;
        }

        public MemoryStatusFilePartition this[int index]
        {
            get
            {
                return this.partitions[index];
            }
        }

        public void Add(
            MemoryStatusFilePartition item
            )
        {
            if (item == null)
            {
                throw new ArgumentNullException(
                    "Parameter cannot be null.",
                    "item"
                    );
            }

            this.partitions.Add(
                item
                );
        }

        public void Clear()
        {
            this.partitions.Clear();
        }

        public bool Contains(
            MemoryStatusFilePartition item
            )
        {
            if (item == null)
            {
                throw new ArgumentNullException(
                    "Parameter cannot be null.",
                    "item"
                    );
            }

            return this.partitions.Contains(
                item
                );
        }

        public void CopyTo(MemoryStatusFilePartition[] array, int arrayIndex)
        {
            throw new NotImplementedException();
        }

        public int Count
        {
            get { return this.partitions.Count; }
        }

        public bool IsReadOnly
        {
            get { throw new NotImplementedException(); }
        }

        public bool Remove(
            MemoryStatusFilePartition item
            )
        {
            if (item == null)
            {
                throw new ArgumentNullException(
                    "Parameter cannot be null.",
                    "item"
                    );
            }

            return this.partitions.Remove(
                item
                );
        }

        public IEnumerator<MemoryStatusFilePartition> GetEnumerator()
        {
            return this.partitions.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            throw new NotImplementedException();
        }

        public void FixEndOffsets()
        {
            List<MemoryStatusFilePartition> partitions = new List<MemoryStatusFilePartition>();

            if (this.Count == 0)
            {
                return;
            }

            for (int i = 0; i < this.Count; i++)
            {
                if (i == this.Count - 1)
                {
                    FileStream fs = File.OpenRead(
                        this.InputFile
                        );

                    int fileLength = 0;

                    using (fs)
                    {
                        fileLength = (int)fs.Length;	
                    }

                    partitions.Add(
                        new MemoryStatusFilePartition(this.partitions[i].StartOffset, fileLength)
                        );
                }
                else
                {
                    partitions.Add(
                        new MemoryStatusFilePartition(this.partitions[i].StartOffset, this.partitions[i + 1].StartOffset - 1)
                        );
                }
            }

            this.partitions.Clear();

            this.partitions.AddRange(
                partitions
                );
            
        }
    }
}
